import 'dart:async';

import 'package:collection/collection.dart';
import 'package:get/get.dart';
import 'package:xuance/bean/GlobalType.dart';
import 'package:xuance/bean/MidChartbean.dart';
import 'package:xuance/bean/ReceiveDatabean.dart';
import 'package:xuance/bean/SnortBean.dart';
import 'package:xuance/bean/StatisticBean.dart';
import 'package:xuance/bean/StatisticTopBean.dart';
import 'package:xuance/bean/exp.dart';
import 'package:xuance/bean/ext.dart';
import 'package:xuance/bean/global_event_bean.dart';
import 'package:xuance/main.dart';
import 'package:xuance/network/api/CommonApi.dart';
import 'package:xuance/network/api/SnortApi.dart';
import 'package:xuance/util/common_util.dart';
import 'package:xuance/util/toast_util.dart';

import 'state.dart';

class RuleWarnLogic extends GetxController {
  final RuleWarnState state = RuleWarnState();
  RxInt page = 1.obs;

  StreamSubscription<GlobalEventBean>? listener;
  @override
  void onInit() {
    super.onInit();

    listener = eventBus.on<GlobalEventBean>().listen((event) {
      if (event.type == GlobalType.updateDate) {
        var bean = event.data as ReceiveDataBean;
        state.dateType.value = bean.time;
        state.queryCondition.value = bean.txt;
        init();
      }
    });

    init();
  }

  Future<void> getList(time) async {
    try {
      if (state.isEventChart.value) {
        List<MidChartbean> res = await SnortApi.midData(
            time[0], time[1], state.queryCondition.value);
        state.lowList.clear();
        state.mediumList.clear();
        state.highList.clear();
        state.highList
            .addAll(res.where((m) => m.warningLevel == "high").toList());
        state.lowList
            .addAll(res.where((m) => m.warningLevel == "low").toList());
        state.mediumList
            .addAll(res.where((m) => m.warningLevel == "medium").toList());
      } else {
        SnortBean? tmp = await SnortApi.getList(
            time[0], time[1], page.value, state.queryCondition.value);
        state.allList.clear();
        state.allList.addAll(tmp?.list ?? []);
        if (state.allList.isNotEmpty) {
          state.pageSize.value = state.allList.first.pageSize?.toInt() ?? 0;
        }
      }
    } catch (e) {
      if (e is ApiException) {
        showToast(e.message);
      } else {
        showToast("$e");
      }
    }
  }

  void nextPage() {
    if (page.value < state.pageSize.value) {
      page++;
      var time = getTime(state.dateType.value);
      getList(time);
    } else {
      showToast("已经是最后一页");
    }
  }

  void lastPage() {
    if (page.value == 1) {
      showToast("已经是第一页");
    } else {
      page--;
      var time = getTime(state.dateType.value);
      getList(time);
    }
  }

  Future<void> init() async {
    var time = getTime(state.dateType.value);
    getList(time);
    getSnortData(time);
    await getStatisticData(refresh: true);
  }

  Future<void> getSnortData(List<String> time) async {
    try {
      var temPieData = await SnortApi.getSnortData(
          startTime: time[0],
          endTime: time[1],
          queryCondition: state.queryCondition.value);
      state.eventFeatureList.clear();
      state.eventFeatureList.addAll(temPieData);
      state.eventFeatureList.makeColors();
    } catch (e) {
      print(e);
      print("获取snort柱状图失败");
    }
  }

  Future<void> getStatistic(List<String> time) async {
    try {
      state.statisticTotal.value = state.statisticDataList.length;
      List<StatisticTopBean> tops = [];
      groupBy(state.statisticDataList, (m) => getGroupWay(m)).forEach((k, v) {
        var list = v.toList();
        tops.add(
            StatisticTopBean(attackIp: v.first.paSip.toString(), list: list));
      });

      state.statisticList.clear();
      List<StatisticTopBean> sortedBy = tops.take(10).toList();
      sortedBy.sort((a, b) => b.list.length.compareTo(a.list.length));

      state.statisticList.addAll(sortedBy);
    } catch (e) {
      print(e);
      print("获取snort柱状图失败");
    }
  }

  getGroupWay(StatisticBean m) {
    if (state.groupWay.value == 1) {
      return m.paSip;
    }
    if (state.groupWay.value == 2) {
      return m.paDip;
    }
    if (state.groupWay.value == 3) {
      return m.paSport;
    }
    return m.paDport;
  }

  Future<void> getStatisticData({bool refresh = false}) async {
    var time = getTime(state.dateType.value);
    if (state.statisticDataList.isEmpty && refresh) {
      var res = await CommonApi.getStatistic(
          startDate: time[0],
          endDate: time[1],
          queryCondition: state.queryCondition.value);
      state.statisticDataList.addAll(res);
    }
    await getStatistic(time);
  }

  @override
  void onClose() {
    super.onClose();
    listener?.cancel();
  }
}
